package pcb.views 
{
	import com.intel.core.UIComponent;
	import com.intel.patterns.observer.Subject;
	import com.intel.utils.Debugger;
	import com.intel.utils.SoundManager;
	import com.intel.utils.TextRender;
	import com.intel.utils.TransitionManager;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.system.System;
	import flash.text.TextField;
	import flash.utils.getTimer;
	import pcb.models.AssetModel;
	import pcb.models.LessonStateModel;
	import pcb.models.ModelLocator;
	import pcb.models.Notifications;
	import pcb.models.PlayerSettings;
	import pcb.models.PlayerStateModel;
	import pcb.models.vo.Annotation;	
	import pcb.models.vo.IPage;
	import pcb.models.vo.NarrativeVo;
	import pcb.models.vo.PageTypes;
	import pcb.models.vo.Slide;
	import pcb.views.library.AnnotationMC;
	import pcb.views.library.FIB;
	import pcb.views.library.LabelWrapper;
	import pcb.views.library.NamingConvention;
	import pcb.views.library.ShowMe;
	import pcb.views.uievents.LabelEvent;
	import pcb.views.uievents.SlideEvent;
	
	import pcb.models.vo.Interaction;
	
	import pcb.scorm.SCORMRuntime;

	
	/**
	 * ContentScreen corresponds to the main timeline of the lesson fla
	 * @author Fintan Boyle
	 */
	public class ContentScreen extends UIComponent 
	{
		private var mainStage:MovieClip;		
		private var mcVoText:MovieClip;
		
		private var currentInteraction_mc:MovieClip;
		
		private var mcAnnotation:annotationMovieClip;
		
		
		private var transitionManager:TransitionManager;
		private var soundManager:SoundManager;
		
		private var currentSlideId:String = null;
		
		private var currentInteraction:Interaction = null;
		
		private var currentSlideType:String;
		
		private var slideAnimationComplete:Boolean;
		private var slideSoundComplete:Boolean;
		
		//presentation model
		private var playAudio:Boolean;
		private var autoSlideTransition:Boolean;
		private var isMuted:Boolean;
		
		protected static var models:ModelLocator = ModelLocator.getInstance();
		private var currentPage:IPage;
		
		private var messageScreen:MessagesScreen;
		
		private var activityNoteStr:String = "Scroll down to see all instructions.";
		
		public function ContentScreen() 
		{
			addListeners();
			transitionManager = new TransitionManager();
			mcVoText = this.getAppRoot().getChildByName("mcVoText") as MovieClip;			
			messageScreen = new MessagesScreen();
		}
		
		/**
		 * note: not implementing IObserver or observing lesson model but
		 * 		 being feed update from mediator that is
		 * @param	o
		 * @param	infoObj
		 */
		public function update(o:Subject, infoObj:Object):void 
		{
			if (infoObj.datatype == Notifications.LESSON_STATUS_CHANGED) {
				
				var lessonState:LessonStateModel = LessonStateModel(o);
				var currentPageType:String = lessonState.currentPage.getPageType();
				if (currentPageType == PageTypes.SLIDE) {
					currentSlideType = Slide(lessonState.currentPage).getPedagogy();
				}else {
					currentSlideType = "";
				}
				
				if (lessonState.status == LessonStateModel.PLAYING) {
					currentPage = lessonState.currentPage;
					Debugger.traceOut("LessonStateModel.PLAYING > play in the swf");
					changePage(lessonState, lessonState.currentPage);
					
				}else if (lessonState.status == LessonStateModel.STOPPED) {
					Debugger.traceOut("LessonStateModel.STOPPED > stop the swf");
					stopLesson();
				}else if (lessonState.status == LessonStateModel.PAUSED) {
					Debugger.traceOut("LessonStateModel.PAUSED > pause the swf");
					pausePage(lessonState.currentPage);
				} else if (lessonState.status == LessonStateModel.NEXT_INTERACTIVITY) {
					Debugger.traceOut("LessonStateModel.NEXT INTER in content screen");
					
					nextInteractivity(lessonState);
				}
				
			}else if (infoObj.datatype == Notifications.ASSET_MODEL_CALLING) {
				
				soundManager = AssetModel(o).getSoundManager();
				
			}else if (infoObj.datatype == Notifications.PLAY_AUDIO_SET) {
				
				playAudio = PlayerSettings(o).playAudio;
				
				autoSlideTransition = PlayerSettings(o).autoSlideTransition;
				
			}if (infoObj.datatype == Notifications.MUTE_AUDIO_SET) {
				isMuted = PlayerStateModel(o).isMuted;
			}
		}
		
		private function stopLesson():void 
		{
			
			if (mainStage.mcLessonPart != null) {
				setVoText("");
				mainStage.gotoAndStop(1);
				stopCurrentSound();
			}
			
		}
		
		public function preInitialise():void 
		{
			clearMainStage();
		}
		
		private function nextInteractivity(lessonState:LessonStateModel):void 
		{
			
			var s:Slide = lessonState.currentPage as Slide;
			currentInteraction = s.getInteractionByID(lessonState.getCurrentInteractionId());
			
			var mcName:String = NamingConvention.SLIDE_PREFIX + s.getId();
			var mc:MovieClip = mainStage.mcLessonPart.getChildByName(mcName);			
			transitionManager.nextFrame(mc);
			
		}
		
		public function mutePage(boo:Boolean):void 
		{
			
			var vol:Number = (boo)?0:1;
			if (currentSlideId != null) soundManager.setSoundVolume(currentSlideId,vol);
			
		}
		
		public function showVoText(boo:Boolean):void 
		{
			
			mcVoText.visible = boo;
			
		}
		
		public function setVoText(str:String, slide_type:String=Slide.DIDACTIC):void 
		{
			
			mcVoText.gotoAndStop(slide_type);
			TextRender.createLabel(mcVoText.txtVOtext, str);
			
		}
		
		private function formatText(str:String):String
		{			
			str = str.replace("\r ", "\r");
			str = str.replace("&apos;", "'");
			str = str.replace("&quot;", "\"");			
			str = str.replace("\r\n", "\r");	
			str = str.replace("&lt;", "<");	
			str = str.replace("&gt;", ">");	
			str = str.replace("&amp;&", "&");	
			str = str.replace("&amp;", "&");	
			//str = str.replace("", "");	
			return str;
		}
		
		public function stopCurrentSound():void 
		{
			
			if (currentSlideId != null) soundManager.stopSound(currentSlideId);
			
		}
		
		private function pausePage(page:IPage):void 
		{
			
			transitionManager.pauseCurrentFrame(mainStage, page.getContainerId());
			
			stopCurrentSound();
			/*
			 //use this if block to truly pause a sound (instead of stopCurrentSound())
			if ((page as Slide).getVO().sound) {
				soundManager.pauseSound(currentSlideId);
			}*/
			

		}
		
		private var wasVoVisible:Boolean = true;
		
		private function changePage(lessonState:LessonStateModel, page:IPage):void 
		{
			stopCurrentSound();
			
			slideAnimationComplete = slideSoundComplete = false;
			//showVoText(wasVoVisible);
			
			if (page.getPageType() == PageTypes.SLIDE) {
				
				var slide:Slide = (page as Slide);				
				setVoText(slide.getVO().votext, slide.getPedagogy());				
				messageScreen.hideActivityCard();
				
				if (slide.getPedagogy() == Slide.ACTIVITY_CARD) {
					
					//wasVoVisible = mcVoText.visible;
				
					//showVoText(false);
					setVoText(activityNoteStr, slide.getPedagogy());
					addChild(messageScreen);
					messageScreen.showActivityCard(slide.getVO().votext);
					
				} else if (slide.getPedagogy() == Slide.INTERACTIVE) {
					currentInteraction = slide.getInteractionByID(lessonState.getCurrentInteractionId());
				} else {				
					if (slide.getVO().sound) {
						
						if (currentSlideId != null) {
							soundManager.setSoundVolume(currentSlideId, 0);
							var channel:SoundChannel = soundManager.getSoundChannel(currentSlideId);
							if(channel != null) if (channel.hasEventListener(Event.SOUND_COMPLETE)) {
								channel.removeEventListener(Event.SOUND_COMPLETE, slide_onComplete);
							}
						}
						
						currentSlideId = slide.getVO().getId();
						
						soundManager.playSound(currentSlideId);
						//mutePage(lessonState.isMuted); //lesson level mute setting
						mutePage(isMuted);//player level mute setting
						
						var curSndChannel:SoundChannel = soundManager.getSoundChannel(currentSlideId);
						if (curSndChannel != null) {
							//TODO:  possible prolonged holding of reference here if slide does not play to completion
							curSndChannel.addEventListener(Event.SOUND_COMPLETE, slide_onComplete, false, 0, true);
						}
						
					} else {
						trace("NO AUDIO");						
					}
				}
				transitionManager.changeFrame(mainStage, page.getContainerId(), page.getId(), null, (slide.getPedagogy() == Slide.DIDACTIC));				
			}else if (page.getPageType() == PageTypes.END_OF_LESSON) {
				Debugger.traceOut("it's the end of the lesson");
				
				if (models.playerSettings.useScorm) {
					/*
					var scormRuntime:SCORMRuntime = SCORMRuntime.getInstance();
					scormRuntime.connect();
					
					scormRuntime.setLessonStatus(SCORMRuntime.LESSON_COMPLETED);

					var date:Date = new Date();
					var time:String = date.getHours() + ":" + date.getMinutes() + ":00.00";

					scormRuntime.updateSessionTime(time);
					scormRuntime.disconnect();
					*/
					SCORMRuntime.getInstance().setLessonComplete();
				}
				
				
				transitionManager.pauseCurrentFrame(mainStage, currentPage.getContainerId());
				currentPage = null;
			}
		}

		private function slide_onComplete(e:Event):void 
		{
			
			//interactive slides are not automated
			Debugger.traceOut("slide_onComplete called " + e.type);
			if (currentSlideType != Slide.INTERACTIVE) {
				if (e.type == Event.SOUND_COMPLETE) {
					slideSoundComplete = true;					
					if (e.target.hasEventListener(Event.SOUND_COMPLETE)) {
						e.target.removeEventListener(Event.SOUND_COMPLETE, slide_onComplete);
					}
					e.target.removeEventListener(Event.SOUND_COMPLETE, slide_onComplete);
					trace("sound finished!");
				} else if (e.type == SlideEvent.ANIMATION_ENDED) {
					if (e.target.hasEventListener(SlideEvent.ANIMATION_ENDED)) {
						e.target.removeEventListener(SlideEvent.ANIMATION_ENDED, slide_onComplete);
					}
					slideAnimationComplete = true;
					trace("animation finished!");
				}
				if(slideAnimationComplete && slideSoundComplete || !playAudio && slideAnimationComplete) {
					Debugger.traceOut("slide is finito", Debugger.DEV);
					slideAnimationComplete = slideSoundComplete = false;
					
					dispatchEvent(new Event(SlideEvent.COMPLETE));
				}
				
			}
			
		}
		
		public function showMe():void 		
		{
			
			//Debugger.traceOut("showMe called in content screen " + currentInteraction_mc);
			if (currentInteraction_mc != null) {
				currentInteraction_mc.showMe();				
			}
			
		}
		
		private function interactivity_onCreate(e:Event):void 
		{
			
			Debugger.traceOut("interactivity created");
			
			currentInteraction_mc = e.target as MovieClip;
			
			if(currentInteraction != null) {			
				if (currentInteraction.annotation != null) {				
					mcAnnotation = new annotationMovieClip();					
					mcAnnotation.text = currentInteraction.annotation.label;
					mcAnnotation.orientation = currentInteraction.annotation.orentation;
					
					currentInteraction_mc.addAnnotation(mcAnnotation);
					mcAnnotation.repositionTo(currentInteraction_mc.getAnnotationMcPosition());
				}
				
				if (currentInteraction.type == Interaction.FIB) {
					FIB(currentInteraction_mc).setCorrectAnswer(currentInteraction.answer);
				}
			}
			
		}
		
		private function interactivity_onComplete(e:Event):void 
		{
			
			currentInteraction_mc = null;
			dispatchEvent(new Event(Interaction.COMPLETE));			
			
		}
		
		private function addListeners():void 
		{
			trace("ADDListeners called");
			this.addEventListener(LabelEvent.ADDED_TO_STAGE, slideLabelAdded);
			//define listeners here that are listening for bubbled events from the swf file
			this.addEventListener(SlideEvent.ANIMATION_ENDED, slide_onComplete);
			
			//define listener for interactivity created
			this.addEventListener(SlideEvent.INTERACTIVITY_CREATED, interactivity_onCreate);
			//		
			//define listener for interactivity complete
			this.addEventListener(SlideEvent.INTERACTIVITY_COMPLETED, interactivity_onComplete);
		}
		
		private function removeListeners():void 
		{
			if(this.hasEventListener(LabelEvent.ADDED_TO_STAGE)){
				this.removeEventListener(LabelEvent.ADDED_TO_STAGE, slideLabelAdded);
			}
			
			if(this.hasEventListener(SlideEvent.ANIMATION_ENDED)){
				this.removeEventListener(SlideEvent.ANIMATION_ENDED, slide_onComplete);			
			}
			
			if(this.hasEventListener(SlideEvent.INTERACTIVITY_CREATED)){
				this.removeEventListener(SlideEvent.INTERACTIVITY_CREATED, interactivity_onCreate);
			}
			if(this.hasEventListener(SlideEvent.INTERACTIVITY_COMPLETED)){
				this.removeEventListener(SlideEvent.INTERACTIVITY_COMPLETED, interactivity_onComplete);
			}
		}
		
		private function slideLabelAdded(e:LabelEvent):void 
		{
			var mc:LabelWrapper = e.mc as LabelWrapper;
			createSlideLabel(mc.id, mc);
		}
		
		private function createSlideLabel(in_lbl_id:String, in_mc:MovieClip, in_tf_name:String = "txtLabel"):void 
		{			
			var txtFld:TextField;
			
			if (in_mc.getChildByName(in_tf_name) != null) {
				txtFld = in_mc.getChildByName(in_tf_name) as TextField;
			} else {
				txtFld = in_mc.getChildAt(0) as TextField;
			}
			
			if (txtFld == null) {
				Debugger.traceOut(in_tf_name + " was not found, firstChild was not a textfield in: " + in_mc + ", label id=" + in_lbl_id, Debugger.ERROR);		
				return;
			}
			
			TextRender.createLabel(txtFld, models.localeModel.getLabelbyId(in_lbl_id));			
		}
		
		
		public function addMainStage(mainSwf:MovieClip):void 
		{
			clearMainStage();
			
			mainStage = mainSwf;
			
			addChild(mainStage);
			
			addListeners();
		}
		
		public function clearMainStage():void 
		{
			//trace("System " + System.totalMemory );
			currentSlideId = null;
			currentInteraction_mc = null;
			transitionManager.dispose();
			removeListeners();
			
			if (mainStage) {
				
				mainStage.gotoAndStop(0);//may help with gc
				
				removeChild(mainStage);	
			}
			//TODO Important: need to check for any memory leaks
			
			if (mainStage) mainStage = null;			
			
			TextRender.createLabel(mcVoText.txtVOtext, "");
		}
		
		public function getMainStage():MovieClip {
			return mainStage;
		}
		
	}
	
}